import { Inject, Middleware, httpError, Config } from '@midwayjs/core';
import { NextFunction, Context } from '@midwayjs/koa';
import { JwtService } from '@midwayjs/jwt';

@Middleware()
export class JwtMiddleware {
    @Inject()
    jwtService: JwtService;
    @Config('jwtConfig') // 动态注入配置
    jwtConfig: { secret: string; expiresIn: string | number };
    resolve() {
        return async (ctx: Context, next: NextFunction) => {
            // 判断下有没有校验信息
            if (!ctx.headers['authorization']) {
                throw new httpError.UnauthorizedError('');
            }
            const parts = ctx.headers['authorization'].split(' ');
            if (parts.length !== 2 || parts[0] !== 'Bearer') {
                throw new httpError.UnauthorizedError('');
            }
            const [scheme, token] = parts;
            if (/^Bearer$/i.test(scheme)) {
                try {
                    const result = await this.jwtService.verify(
                        token,
                        this.jwtConfig.secret,
                        { complete: true }
                    );
                    if (typeof result === 'string') {
                        throw new httpError.UnauthorizedError('无效的 token');
                    }
                    ctx.user = result.payload;
                    await next();
                } catch (err) {
                    throw new httpError.UnauthorizedError('无效的 token');
                }
            };
        };
    }
    public match(ctx: Context): boolean {
        const ignoreRoutes = ['/auth/userRegister', '/auth/userLogin'];
        const ignore = ignoreRoutes.some(route => ctx.path.indexOf(route) !== -1);
        return !ignore;
    }
    public static getName(): string {
        return 'jwt';
    }
}
